home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / vol05 / 05 / parallel / sendfile.c < prev    next >
Text File  |  1990-09-01  |  9KB  |  357 lines

  1. /***************************
  2.  sendfile.c
  3.  
  4.  Ross M. Greenberg
  5.  
  6.  Thursday, August 2, 1990
  7.  Microsoft C 5.1
  8.  **************************/
  9.  
  10. #include   <stdio.h>
  11. #include   <fcntl.h>
  12. #include   <dos.h>
  13. #include   <sys/types.h>
  14. #include   <sys/stat.h>
  15. #include   <io.h>
  16.  
  17. #define FALSE 0
  18. #define TRUE  1
  19. #define REC_SIZE (30 * 1024)
  20. #define S_SIZE   REC_SIZE
  21.  
  22. char file_name[128];
  23. #define BIG_BUF_SIZE   (30 * 1024)
  24.  
  25. char big_buffer[BIG_BUF_SIZE + 1024];
  26. void send_control();
  27. void get_control();
  28.  
  29. /********************************************************************
  30. * do_sync(port)  -
  31. *
  32. * Syncing up two machines where either can be master or slave is a
  33. * bit of a kludge. The 1st machine to *not* get a character sends an
  34. * uppercase 'I'. When a machine receives an uppercase 'I' it responds
  35. * with a lowercase 'i'.  If a machine gets a lowercase 'i', it will
  36. * respond with an uppercase 'I'.  This continues until there are a
  37. * total of three transactions.  Then both machines start sending 'x'
  38. * until it gets one back or, out of exhaustion from this kludge, the
  39. * user hits a key.
  40. ********************************************************************/
  41.  
  42. void
  43. do_sync(int port)
  44. {
  45. char c = 0;
  46. int  stat;
  47. int  cnt = 0;
  48.  
  49.   printf("Syncing machines...\n");
  50.   pinit(port);
  51.  
  52.  
  53.   do
  54.   {
  55.      stat = prec(&c, 1);
  56.      printf(stat == 1 ? "%c" : "-", c);
  57.      if (stat != 1)
  58.      {
  59.         psend("I", 1);
  60.      }
  61.      else
  62.      switch (c)
  63.      {
  64.         case 'I':
  65.            psend("i", 1);
  66.            cnt++;
  67.            break;
  68.  
  69.         case 'i':
  70.            psend("I", 1);
  71.            cnt++;
  72.            break;
  73.  
  74.         case 'x':
  75.            psend("x", 1);
  76.            cnt++;
  77.            break;
  78.  
  79.         default:
  80.            printf("(%c)", c);
  81.            break;
  82.      }
  83.   }
  84.   while (cnt < 4 && !kbhit());
  85.   do
  86.   {
  87.      prec(&c, 1);
  88.      psend("x", 1);
  89.   }
  90.   while (c != 'x' && !kbhit());
  91.  
  92.   /* gobble up any spare characters. sleep(1) in main gulps this */
  93.   while (prec(&c, 1) > 0)
  94.      ;
  95. }
  96.  
  97.  
  98. /********************************************************************
  99. * main()   -
  100. *
  101. * Get the port (0,1,2...n)
  102. * Get status as sender or receiver
  103. * If Sender:
  104. *    Get file name and make sure file exists.
  105. *    Sync up the two machines and their ports.
  106. *    Hangout for one second to gobble routine in do_sync eats
  107. *      nothing of value.
  108. *    Open the file, send a rather verbose message on the filename.
  109. *      these messages could easily be reduced to single control
  110. *      bytes.  Send CAN message if can not open file.
  111. *    Get remote status of file open.  If not okay, fail
  112. *    Get file length and send it across in ASCII
  113. *    Get OK status from remote
  114. *    Get start time.
  115. *    Send a large block across, continue until file is exhausted.
  116. *     Get status information for each block sent.
  117. *    When done, get end time, calculate bytes per second, and exit.
  118. *
  119. * If Receiver:
  120. *    Sync
  121. *    Get filename and filesize, display them
  122. *    Get start time
  123. *    Try to read a big block.  Hi bit set indicates a short block
  124. *      If short:
  125. *         Strip off the hi bit, to get number of bytes received.
  126. *                    If no bytes, display a '?' for timeout.
  127. *      If bytes:
  128. *         Add them to buffer, when buffer size is ready, write
  129. *         to disk, send an okay message, and (remember ASCOM?)
  130. *         display a '*' for each block.
  131. *    Loop until all bytes received
  132. *    Write a final block if required
  133. *    Close the file.
  134. *    When done, get end time, calculate bytes per second, and exit.
  135. ********************************************************************/
  136.  
  137. void
  138. main()
  139. {
  140. char buf[128];
  141. int  port;
  142. int  cnt = 0;
  143. unsigned stat;
  144. char *p;
  145. int  fd;
  146. long tot_bytes = 0;
  147. long file_size = 0;
  148. long get_time();
  149. long time1,
  150.   time2;
  151. char c;
  152.  
  153.   printf("What port? (LPT1 = 0):");
  154.   gets(buf);
  155.   port = atoi(buf);
  156.   do
  157.   {
  158.      printf("\n(S)end|(R)eceive:");
  159.      c = getch();
  160.      c = toupper(c);
  161.   }
  162.   while (c != 'S' && c != 'R');
  163.  
  164.   printf("\n");
  165.   if (c == 'S')
  166.   {
  167.      do
  168.      {
  169.         printf("Enter filename:");
  170.         gets(file_name);
  171.      }
  172.      while (access(file_name, 0));
  173.  
  174.      do_sync(port);
  175.      sleep(1);
  176.      prec(big_buffer, 1);
  177.      printf("\nSender Synced\n");
  178.      if ((fd = open(file_name, O_RDONLY | O_BINARY)) == -1)
  179.      {
  180.         printf("Can't open file: %s\n", file_name);
  181.         send_control("CAN", 0, 0, 0);
  182.         exit(1);
  183.      }
  184.      send_control("FILE:%s", file_name, 0, 0);
  185.      get_control(buf);
  186.      if (strcmp(buf, "OK"))
  187.      {
  188.         printf("Error on Remote: %s\n", buf);
  189.         exit(1);
  190.      }
  191.  
  192.      file_size = lseek(fd, 0L, 2);
  193.      sprintf(buf, "SIZE:%lu", file_size);
  194.      send_control(buf, 0, 0, 0);
  195.      get_control(buf);
  196.      if (strcmp(buf, "OK"))
  197.      {
  198.         printf("Error on Remote: %s\n", buf);
  199.         exit(1);
  200.      }
  201.  
  202.      lseek(fd, 0L, 0);
  203.      time1 = get_time();
  204.      while((cnt = read(fd, big_buffer, BIG_BUF_SIZE)))
  205.      {
  206.         psend(big_buffer,cnt);
  207.         tot_bytes += (long)cnt;
  208.         printf("*");
  209.         get_control(buf);
  210.      }
  211.      time2 = get_time();
  212.   }
  213.   else
  214.   {
  215.      do_sync(port);
  216.      prec(big_buffer, 1);
  217.      printf("\nReceiver Synched\n");
  218.      get_control(buf);
  219.      if (!strcmp(buf, "CAN"))
  220.      {
  221.         printf("Remote cancels\n");
  222.         exit(1);
  223.      }
  224.      sscanf(buf, "FILE:%s", file_name);
  225.      if ((fd = open(file_name, O_CREAT | O_WRONLY | O_BINARY,
  226.                                S_IREAD | S_IWRITE)) == -1)
  227.      {
  228.         printf("Can't open file: %s\n", file_name);
  229.         send_control("CAN", 0, 0, 0);
  230.         exit(1);
  231.      }
  232.      send_control("OK", 0, 0, 0);
  233.      get_control(buf);
  234.      sscanf(buf, "SIZE:%lu", &file_size);
  235.      printf("File Size for `%s' is: %ld\n", file_name, file_size);
  236.      tot_bytes = cnt = 0;
  237.      p = big_buffer;
  238.      send_control("OK", 0, 0, 0);
  239.      time1 = get_time();
  240.      while (tot_bytes < file_size)
  241.      {
  242.         stat = prec(p, REC_SIZE);
  243.         if (stat & 0x8000)
  244.            stat &= 0x7fff;
  245.         if (stat > 0)
  246.         {
  247.            p += stat;
  248.            tot_bytes += stat;
  249.            cnt += stat;
  250.            if (cnt >= BIG_BUF_SIZE)
  251.            {
  252.               write(fd, big_buffer, cnt);
  253.               printf("*");
  254.               send_control("OK", 0, 0, 0);
  255.               cnt = 0;
  256.               p = big_buffer;
  257.            }
  258.         }
  259.         else
  260.            printf("?");
  261.      }
  262.      if (cnt)
  263.      {
  264.         write(fd, big_buffer, cnt);
  265.         printf("*");
  266.         send_control("OK", 0, 0, 0);
  267.         cnt = 0;
  268.      }
  269.      close(fd);
  270.      time2 = get_time();
  271.   }
  272.   printf("\n\nNu}_ber of characters transmitted: %ld\n", tot_bytes);
  273.   printf("Number of Ticks to Transmit: %ld\n", time2 - time1);
  274.   printf("Characters per second: %ld\n",
  275.          (tot_bytes/(time2 - time1)) * 18L);
  276. }
  277.  
  278. /********************************************************************
  279. * send_control(format, var1...varn)
  280. *
  281. * If the format string has a %, do an sprintf into the local stack
  282. * buffer.  Send the control string, followed by a trailing null.
  283. ********************************************************************/
  284.  
  285. void
  286. send_control(char *ptr, int var1, int var2, int var3)
  287. {
  288. char buf[128];
  289. char *p;
  290. char c = 0;
  291.  
  292.   if (strchr(ptr, '%'))
  293.   {
  294.      sprintf(buf, ptr, var1, var2, var3);
  295.      p = buf;
  296.   }
  297.   else
  298.      p = ptr;
  299.  
  300.   psend(p, strlen(p));
  301.   psend(&c, 1);
  302. }
  303.  
  304. /********************************************************************
  305. * get_control(ptr)
  306. *
  307. * stuffs characters into buffer @ptr until it receives trailing NULL
  308. ********************************************************************/
  309. void
  310. get_control(char *ptr)
  311. {
  312. int  stat;
  313. char *ptr1 = ptr;
  314.  
  315.   while (!kbhit())
  316.   {
  317.      stat = prec(ptr, 1);
  318.      if (stat <= 0)
  319.         continue;
  320.      if (!*ptr)
  321.         return;
  322.      ptr++;
  323.   }
  324. }
  325.  
  326.  
  327. /********************************************************************
  328. * get_time();
  329. *
  330. * Using INT 0x1a, returns the number of ticks since birth
  331. ********************************************************************/
  332.  
  333. long
  334. get_time()
  335. {
  336. union   REGS  regset;
  337.  
  338.   regset.x.ax = 0;
  339.   int86(0x1a, ®set, ®set);
  340.   return(((long) regset.x.cx << 16) | (long)regset.x.dx);
  341. }
  342.  
  343. /********************************************************************
  344. * sleep();
  345. *
  346. * Eat up time since sleep() is not in library
  347. ********************************************************************/
  348.  
  349. sleep(int seconds)
  350.  
  351. {
  352. long time1 = get_time();
  353.  
  354.   while ((get_time() - time1) <= (long)seconds * 18L )
  355.      ;
  356. }
  357.